DO NOT MERGE — CI proof for #63: deliberate label drift - #70
Conversation
`src/translations/en.ts` restates the English labels that already exist inline in the object, view, app, dashboard and dataset definitions, so the two locale files diff line for line. Nothing checked that the restatement was still true: rename a label in an object file and the bundle keeps serving the old string to every English user, because a bundle entry wins over the source label at runtime. Measured before this change, on this tree: `pnpm validate`, `pnpm lint --i18n-strict` and `pnpm typecheck` are all green with a drifted entry, and green with a missing `en` entry too — `os i18n check` reports `en` at 100 % (expected 1265 / translated 1265) because the source label counts as the translation for the default locale. Coverage asks whether a key exists, not whether it still says what the metadata says. `scripts/check-i18n-source.mjs` asks the second question. It reads both sides out of `dist/objectstack.json` and fails on a drifted value, a key whose metadata is gone, and a source label the bundle never restates. The source side is collected twice on purpose: `os i18n extract --json` is the platform's own single definition of what is translatable, so a surface the platform adds later arrives here for free; a local resolver covers the view-nested text that walk does not address (a view's default `list`, its `listViews` and its `formViews`). Together they resolve all 507 keys in `en.ts` — every key is compared, none is skipped, and a key shape neither collector knows fails as an orphan rather than passing quietly. `pnpm lint` chains it, so CI and a laptop run it without a fourth command. It runs its own `--self-test` first, on every run: seven assertions that the comparator still reports a mismatch, an orphan and a gap, so the gate proves in CI that it can fail. The real run refuses to report success when either side came back empty, or when the artifact is older than `src/`. Zero findings on this tree today: 507 bundle keys, 507 source labels, 507 compared, 769 platform `metadataForms.*` keys excluded. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PbJ5Cy9KDAzeQHo8bsMadG
DO NOT MERGE. Renames ats_job.fields.status from 'Status' to 'Review status' in the source while src/translations/en.ts still says 'Status', so the CI run on this branch executes pnpm check:i18n-source against a real mismatch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PbJ5Cy9KDAzeQHo8bsMadG
|
Done its job — run 8 failed at the Generated by Claude Code |
This PR's red CI is the deliverable. Not to be fixed, not to be merged.Recording that explicitly so no later pass — mine or an automated one — "drives it to green" and destroys the evidence. Card #63's acceptance asked for two things a green run cannot show: that the new i18n source-parity gate bites, and that it bites in CI rather than only on a developer's laptop. This PR is that proof. I read the failing job (101836788834) and it fails for exactly the right reason: That is the exact mutation the card named, caught by key, with both values printed and a non-zero exit. Three things about that output matter more than the failure itself:
The real PR is #69. This branch exists only to make the CI run above exist, and I will close it once I have reviewed #69 — leaving the run, its logs and this comment as the permanent record. ⛔ Do not merge. Do not re-run. Do not fix the red. Generated by Claude Code |
Throwaway. Opened only so GitHub Actions executes the new gate against a real mismatch, closed as soon as the run reports. Part of #63; the deliverable is #69.
This branch is #69's commit plus one line:
ats_job.fields.statusrenamed fromStatustoReview statusinsrc/objects/job.object.ts, whilesrc/translations/en.tsstill saysStatus. The expectation is that thelintstep of CI fails namingobjects.ats_job.fields.status.label, the bundle's value and the source's.The point of this PR is that a check which only runs on a developer's laptop is not a gate. #69's history stays clean; this one carries the red run.
Generated by Claude Code